package service

import (
	"context"
	"golang.org/x/crypto/bcrypt"
	"happy-book/internal/domain"
	"happy-book/internal/repository"
)

// 异常定义
var (
	ErrDuplicatedEmail        = repository.ErrDuplicatedEmail //使用Type Alias别名机制实现异常传导,避免了跨层依赖的问题
	ErrInvalidEmailOrPassword = repository.ErrUserNotFound
)

// UserService 用户服务
type UserService struct {
	repo *repository.UserRepository
}

// NewUserService 构造函数
// 通过依赖注入UserRepository
func NewUserService(repo *repository.UserRepository) *UserService {
	return &UserService{
		repo: repo,
	}
}

// SignUp 用户注册
func (svc *UserService) SignUp(ctx context.Context, user *domain.User) error {
	//对密码进行加密
	encrypted, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	user.Password = string(encrypted)
	return svc.repo.Create(ctx, user)
}

// Login 用户登录
func (svc *UserService) Login(ctx context.Context, email, password string) (*domain.User, error) {
	//根据邮箱查询用户
	user, err := svc.repo.FindByEmail(ctx, email)
	if err != nil {
		return &domain.User{}, err
	}

	//校验密码
	if user.Id <= 0 {
		return &domain.User{}, ErrInvalidEmailOrPassword
	}

	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) //判断数据库中的密文与用户输入的明文是否匹配
	if err != nil {
		return &domain.User{}, ErrInvalidEmailOrPassword
	}

	return user, nil
}

// Profile 查看用户个人信息
func (svc *UserService) Profile(ctx context.Context, uid int64) (*domain.User, error) {
	return svc.repo.FindById(ctx, uid)
}

// UpdateNonSensitiveInfo 修改除邮箱、密码外等非敏感信息
func (svc *UserService) UpdateNonSensitiveInfo(ctx context.Context, user *domain.User) error {
	//将不需要修改的字段设置为零值
	user.Email = ""
	user.Password = ""
	return svc.repo.Update(ctx, user)
}
